<template>
  <div class="drawing-board" ref="wrapperRef">
    <slot name="content"></slot>
    <canvas
      ref="canvasRef"
      class="canvas"
      :class="{ 'not-draw': props.currentMode === 'select' ? true : false }"
    ></canvas>
  </div>
</template>
<script setup>
import { WebSketch } from '@ebag/web-sketch'
import { ref, watch, nextTick, onBeforeUnmount } from 'vue'
import { useComment, CleanSizeMap } from '@/stores/comment'
const homeworkAssessment = useComment()
const props = defineProps({
  currentMode: {
    default: 'select',
    type: String
  },
  index: {
    default: '',
    type: [String, Number]
  },
  isInheritHeight: {
    default: false,
    type: Boolean
  }
})
const webSketch = ref(null)
const wrapperRef = ref()
const canvasRef = ref()
const ctx = ref()
const emits = defineEmits(['mouse-down', 'touch-start'])

const draw = type => {
  if (!webSketch.value) createCanvas()
  if ((type === 'pen' || type === 'clean') && canvasRef.value) {
    addListener(canvasRef.value)
  }
  switch (type) {
    case 'select':
      if (canvasRef.value) removeListener(canvasRef.value)
      webSketch.value.selectMode()
      break
    case 'pen':
      webSketch.value.setBrushColor(homeworkAssessment.drawingBoard.penColor)
      webSketch.value.setBrushSize(homeworkAssessment.drawingBoard.penSize)
      webSketch.value.brushMode()
      break
    case 'clean':
      webSketch.value.eraserMode()
      webSketch.value.setEraser(
        CleanSizeMap[homeworkAssessment.drawingBoard.cleanSize].width,
        CleanSizeMap[homeworkAssessment.drawingBoard.cleanSize].height,
        CleanSizeMap[homeworkAssessment.drawingBoard.cleanSize].className
      )
      break
  }
}

const revert = type => {
  if (!webSketch.value) createCanvas()
  switch (type) {
    case 'cancel':
      webSketch.value.undo()
      break
    case 'recover':
      webSketch.value.redo()
      break
    case 'delete':
      webSketch.value.reset()
      break
  }
}

// 根据新的高度，缩放画布
const scale = () => {
  nextTick(() => {
    if (wrapperRef.value) {
      const currentHeight = wrapperRef.value.scrollHeight || 0
      const currentWidth = wrapperRef.value?.offsetWidth || 0
      let yRatio = 1
      let xRatio = 1
      if (canvasRef.value) {
        yRatio = currentHeight / canvasRef.value.height
        xRatio = currentWidth / canvasRef.value.width
      }
      // todo: canvas缩放处理
      // if (ctx.value) {
      //   ctx.value.scale(xRatio, yRatio)
      // }
    }
  })
}

const addListener = node => {
  node.addEventListener('mousedown', mouseDownFun)
  node.addEventListener('mouseup', mouseUpFun)
  node.addEventListener('touchstart', touchStart)
  node.addEventListener('touchend', mouseUpFun)
}

const removeListener = node => {
  node.removeEventListener('mousedown', mouseDownFun)
  node.removeEventListener('mouseup', mouseUpFun)
  node.removeEventListener('touchstart', touchStart)
  node.removeEventListener('touchend', mouseUpFun)
}

const touchStart = () => {
  emits('touch-start', props.index)
}

// 鼠标松开事件
const mouseUpFun = () => {
  if (webSketch.value) {
    if (props.currentMode === 'pen') {
      webSketch.value.brushMode()
    } else if (props.currentMode === 'clean') {
      webSketch.value.eraserMode()
    }
  }
}

// 鼠标按下事件
const mouseDownFun = () => {
  emits('mouse-down', props.index)
}

const createCanvas = () => {
  if (canvasRef.value && wrapperRef.value) {
    console.log(
      'create canvas',
      wrapperRef.value.offsetWidth,
      innerWidth,
      wrapperRef.value.scrollHeight,
      innerHeight
    )
    if (
      webSketch.value &&
      canvasRef.value.width >= wrapperRef.value.offsetWidth &&
      canvasRef.value.height >= wrapperRef.value.scrollHeight
    )
      return
    canvasRef.value.style.left = '0'
    canvasRef.value.style.top = '0'
    if (props.isInheritHeight) {
      canvasRef.value.height = wrapperRef.value.scrollHeight
      canvasRef.value.width = wrapperRef.value.offsetWidth
    } else {
      canvasRef.value.height =
        wrapperRef.value.scrollHeight > innerHeight
          ? wrapperRef.value.scrollHeight
          : innerHeight
      canvasRef.value.width =
        wrapperRef.value.offsetWidth > innerWidth
          ? wrapperRef.value.offsetWidth
          : innerWidth
    }
    console.log('res', canvasRef.value.height, canvasRef.value.width)
    webSketch.value = new WebSketch(canvasRef.value)
    ctx.value = canvasRef.value.getContext('2d')
    draw(props.currentMode)
  }
}

// 题目区域修改画布高度, isRepaint表示是否需要把已绘制的内容进行保存，修改高度后重新绘制
const changeCanvasHeight = (isRepaint = false) => {
  if (canvasRef.value && wrapperRef.value) {
    let imageData
    const context = ctx.value
    if (isRepaint && context) {
      // 存储绘图数据
      imageData = context.getImageData(
        0,
        0,
        canvasRef.value.width,
        canvasRef.value.height
      )
    }
    // 先将画布高度置为0，防止影响父元素高度
    canvasRef.value.height = 0
    if (props.isInheritHeight) {
      canvasRef.value.height = wrapperRef.value.scrollHeight
      canvasRef.value.width = wrapperRef.value.offsetWidth
    } else {
      // 修改画布高度
      canvasRef.value.height =
        wrapperRef.value.scrollHeight > innerHeight
          ? wrapperRef.value.scrollHeight
          : innerHeight
      canvasRef.value.width = wrapperRef.value.offsetWidth
    }

    if (isRepaint && ctx.value) {
      // 清空画布
      ctx.value.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height)
      ctx.value.putImageData(imageData, 0, 0)
    }
    draw(props.currentMode)
  }
}

watch(
  () => homeworkAssessment.drawingBoard,
  val => {
    if (webSketch.value) {
      webSketch.value.setBrushColor(val.penColor)
      webSketch.value.setBrushSize(val.penSize)
      webSketch.value.setEraser(
        CleanSizeMap[val.cleanSize].width,
        CleanSizeMap[val.cleanSize].height,
        CleanSizeMap[val.cleanSize].className
      )
    }
  },
  {
    deep: true
  }
)

onBeforeUnmount(() => {
  if (webSketch.value) {
    webSketch.value.destroy()
  }
  if (canvasRef.value) {
    removeListener(canvasRef.value)
  }
})

defineExpose({
  revert,
  draw,
  createCanvas,
  scale,
  changeCanvasHeight
})
</script>
<style lang="less" scoped>
.drawing-board {
  position: relative;
  overflow-x: hidden;
  height: 100%;

  &.not-scroll {
    overflow-y: hidden;
  }
  &::-webkit-scrollbar {
    width: 0px !important;
  }
  .canvas {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;

    &.not-draw {
      pointer-events: none;
    }
  }
}
</style>
<!-- eslint-disable -->
<style lang="less">
.small-eraser {
  border-radius: 10px;
  background: url(@/assets/images/comment/eraser.svg) no-repeat center/cover;
}

.middle-eraser {
  border-radius: 20px;
  background: url(@/assets/images/comment/eraser-middle.svg) no-repeat
    center/cover;
}

.big-eraser {
  border-radius: 30px;
  background: url(@/assets/images/comment/eraser-big.svg) no-repeat center/cover;
}
</style>
